package com.idea.relax.log.props;

import com.idea.relax.log.constant.ApiLogConstant;
import com.idea.relax.log.constant.LogConstant;
import com.idea.relax.log.constant.RequestLogConstant;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;

import java.util.Set;

/**
 * @className: RelaxLogProperties
 * @description: RelaxLog的配置类
 * @author: salad
 * @date: 2022/10/1
 **/
@Getter
@Setter
@ConfigurationProperties(
        prefix = RelaxLogProperties.PREFIX
)
public class RelaxLogProperties {

    public static final String PREFIX = "relax.log";

    public static final String ENABLED = ".enabled";

    /**
     * Kafka日志推送
     */
    private final KafkaLog kafkaLog = new KafkaLog();

    /**
     * Logstash日志推送
     */
    private final LogstashLog logstashLog = new LogstashLog();

    /**
     * 文件日志
     */
    private final FileLog fileLog = new FileLog();

    /**
     * 控制台日志
     */
    private final ConsoleLog consoleLog = new ConsoleLog();

    /**
     * 请求日志
     */
    private final RequestLog requestLog = new RequestLog();

    /**
     * 错误日志
     */
    private final ErrorLog errorLog = new ErrorLog();

    /**
     * 接口操作日志
     */
    private final ApiLog apiLog = new ApiLog();

    /**
     * 异步存储
     */
    private final AsyncThread asyncStorage = new AsyncThread();

    /**
     * 是否开启RelaxLog，默认关闭
     */
    private boolean enabled = false;




    @Getter
    @Setter
    public static class AsyncThread {
        public static final String PREFIX = RelaxLogProperties.PREFIX + ".async-thread";

        /**
         * 是否启用异步存储，默认开启
         */
        private boolean enabled = true;

        /**
         * 核心线程数
         */
        private Integer corePoolSize = 8;

        /**
         * 最大线程数
         */
        private Integer maximumPoolSize = 16;

        /**
         * 存活时间，单位 毫秒
         */
        private Long keepAliveTime = 1000L;

        /**
         * 队列最大容量
         */
        private Integer queueCapacity = 512;

    }


    @Getter
    @Setter
    public static class ConsoleLog {
        public static final String PREFIX = RelaxLogProperties.PREFIX + ".console-log";

        /**
         * 是否在服务启动后关闭控制台日志
         */
        private boolean closeOnRunAfter = false;

        /**
         * appender名称
         */
        private String appenderName = "CONSOLE";


    }

    @Getter
    @Setter
    public static class FileLog {
        public static final String PREFIX = RelaxLogProperties.PREFIX + ".file-log";

        /**
         * 是否开启File形式的日志
         */
        private boolean enabled = true;

        /**
         * 是否启用异步存储，默认关闭
         */
        private boolean asyncAppender = false;

        /**
         * 是否使用Json格式化日志
         */
        private boolean useJsonFormat = false;

        /**
         * appender名称的前缀
         */
        private String appenderNamePrefix = "FILE_";

        /**
         * 日志等级，可配置多个
         */
        private Set<LogLevel> logLevels = LogConstant.FILE_LOG_LEVELS;


    }

    @Getter
    @Setter
    public static class ApiLog {
        public static final String PREFIX = RelaxLogProperties.PREFIX + ".api-log";

        /**
         * 是否开启操作日志
         */
        private boolean enabled = false;

        /**
         * 保留的最大响应响应数据字节数
         * 如果配置为null或者0，则不会截取
         */
        private Integer maxRespDataLength = 1500;

        /**
         * 操作日志的切入点表达式
         */
        private String pointcutExp = ApiLogConstant.API_LOG_EXP;

    }

    @Getter
    @Setter
    public static class RequestLog {
        public static final String PREFIX = RelaxLogProperties.PREFIX + ".request-log";

        /**
         * 是否开启请求日志
         */
        private boolean enabled = false;

        /**
         * 开启链路日志模式
         */
        private boolean enabledTraceMode= false;

        /**
         * 请求日志的模式
         */
        private Set<RequestLogMode> requestLogMode = RequestLogConstant.DEFAULT_MODES;

        /**
         * 是否向MDC中添加内置的属性（具体属性请参考relax-log文档）
         * 一般配合relax.log.file-log.use-json-format配置项一起开启
         */
        private boolean addRichFields = false;

        /**
         * 保留的最大响应响应数据字节数
         * 如果配置为null或者0，则不会截取
         */
        private Integer maxRespDataLength = 1500;

        /**
         * 请求日志的切入点表达式
         */
        private String pointcutExp = RequestLogConstant.RESP_LOG_EXP;


    }

    @Getter
    @Setter
    public static class ErrorLog {
        public static final String PREFIX = RelaxLogProperties.PREFIX + ".error-log";

        /**
         * 是否开启错误日志
         */
        private boolean enabled = true;

        /**
         * 主启动类所在的包路径
         * 比如：com.idea.relax.log.Application，则包路径为；com.idea.relax.log
         * 如果不配置，RelaxLog在服务启动时将会自动计算
         */
        private String appPackagePrefix;


    }

    @Getter
    @Setter
    public static class LogstashLog {
        public static final String PREFIX = RelaxLogProperties.PREFIX + ".logstash-log";

        /**
         * 是否开启 logstash 日志收集
         */
        private boolean enabled = false;

        /**
         * 是否启用异步存储，默认关闭
         */
        private boolean asyncAppender = false;

        /**
         * 目标地址，默认： localhost:5000，示例： host1.domain.com,host2.domain.com:5560
         */
        private String destinations = "localhost:5000";

        /**
         * 日志等级，可配置多个
         */
        private Set<LogLevel> logLevels = LogConstant.LOGSTASH_LOG_LEVELS;

        /**
         * logstash 队列大小
         */
        private int ringBufferSize = 1024;

        /**
         * appender名称的前缀
         */
        private String appenderNamePrefix = "LOGSTASH_";


    }

    @Getter
    @Setter
    public static class KafkaLog {
        public static final String PREFIX = RelaxLogProperties.PREFIX + ".kafka-log";

        /**
         * 是否启用kafka日志推送
         */
        private boolean enabled = true;

        /**
         * 是否启用异步存储，默认关闭
         */
        private boolean asyncAppender = false;

        /**
         * 日志推送的topic名称
         */
        private String topic = "relax_log_topic";

        /**
         * appender名称的前缀
         */
        private String appenderNamePrefix = "KAFKA_";

        /**
         * 日志等级，可配置多个
         */
        private Set<LogLevel> logLevels = LogConstant.KAFKA_LOG_LEVELS;

    }

}
